package com.strongbj.iot.devices.newlight.response.handle;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.strongbj.core.message.IMessageHandle;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.core.util.ContextUtils;
import com.strongbj.iot.devices.newlight.common.Executer;
import com.strongbj.iot.devices.newlight.entity.ActiveTagData;
import com.strongbj.iot.devices.newlight.entity.Tag;
import com.strongbj.iot.devices.newlight.message.NewLightMQMessage;
import com.strongbj.iot.devices.newlight.message.NewLightReaderMessage;
import com.strongbj.iot.devices.newlight.request.handle.ActiveTagHandle;
import com.strongbj.iot.devices.newlight.response.common.HandleTimeStamp;
import com.strongbj.iot.devices.newlight.service.TagService;
import com.strongbj.iot.mq.producer.TopicSender;

import cn.hutool.core.date.DateUtil;
import io.netty.channel.ChannelHandlerContext;

/**
 * 0x06，指定标签 LED 控制（最大 5 个），标签地址可不连续
 * 
 * @author lei_w
 *
 */
public class MultiLabelLedControlResponseHandle implements IMessageHandle<NewLightReaderMessage, Object> {
	private static Logger logger = LogManager.getLogger(MultiLabelLedControlResponseHandle.class.getName());
	private TagService tagService = (TagService) ContextUtils.getBean("tagService");
	private TopicSender topicSender = (TopicSender) ContextUtils.getBean("topicSender");

	@Override
	public boolean isHandle(NewLightReaderMessage t) {
		if (Integer.valueOf("6", 16).byteValue() == t.getType()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object handle(ChannelHandlerContext ctx, NewLightReaderMessage t) {
		if(ByteUtil.byteArrayToInt(t.getTime()) == Executer.currentSequence) {
			Executer.currentThread.stop();
		}
		
		String hostNumber = ByteUtil.bytesToAddress(t.getAddress()); // reader 地址码
		String timeStamp = ByteUtil.byteArrToHexString(t.getTime()); // 时间戳

		short ctrlSuccNum = ByteUtil.byteArrToShort(t.getBody(), 0); // 控制成功个数
		// String ctrlState = ByteUtil.byteArrToHexString(t.getBody(), 2, 6); // 控制后 LED
		// 状态
		String tagState = ByteUtil.byteToBitString(ByteUtil.subBytes(t.getBody(), 2, 1)[0]); // 标签其他状态
		String powerState = tagState.substring(5, 8);
		String fbState = tagState.substring(3, 5);
		String fsState = tagState.substring(2, 3);
		String ledState = ByteUtil.byteToBitString(ByteUtil.subBytes(t.getBody(), 3, 1)[0]); // 标签LED状态
		String led1State = ledState.substring(6, 8);
		String led2State = ledState.substring(4, 6);
		String led3State = ledState.substring(2, 4);
		String led4State = ledState.substring(0, 2);
		short ctrlFailNum = ByteUtil.byteArrToShort(t.getBody(), 8); // 控制失败个数
		String ctrlFailShortAddress = ByteUtil.byteArrToHexString(t.getBody(), 10, ctrlFailNum * 2); // 控制失败段地址
		String log = "\r\n===================================================" + "\r\n收到指定标签 LED控制返回报文：" + "\r\n地址码："
				+ hostNumber + "\r\n控制成功个数：" + ctrlSuccNum + "\r\n标签电量状态：  " + powerState + "\r\n功能按键状态：  " + fbState
				+ "\r\n防撕状态：" + fsState + "\r\nLED1状态：" + led1State + "\r\nLED2状态：" + led2State + "\r\nLED3状态："
				+ led3State + "\r\nLED4状态：" + led4State + "\r\n控制失败个数：" + ctrlFailNum + "\r\n控制失败段地址："
				+ ctrlFailShortAddress + "\r\n时间戳：" + HandleTimeStamp.handle(timeStamp) + "\r\n时间戳：" + timeStamp;
		logger.info(log);
		// 获取失败的点亮标签短地址
		List<String> failShortAddrs = new ArrayList<>();
		for (int i = 0; i < ctrlFailNum; i++) {
			String tag = ByteUtil.bytesToIp(t.getBody(), 10 + i * 2);
			failShortAddrs.add(tag);
		}

		ByteUtil.byteArrToHexString(t.getBody(), 10, ctrlFailNum * 2);
		String key = ByteUtil.byteArrToHexString(t.getTime()) + hostNumber;
		if (ActiveTagHandle.activeTagMap.containsKey(key) == false)
			return null;
		List<String> shortAddrs = ActiveTagHandle.activeTagMap.get(key);
		ActiveTagHandle.activeTagMap.remove(key);
		List<String> successTags = new ArrayList<>();
		List<String> failTags = new ArrayList<>();
		for (String st : shortAddrs) {
			QueryWrapper<Tag> wrapper = new QueryWrapper<Tag>();
			wrapper.eq("short_address", st);
			wrapper.eq("reader_", hostNumber);
			Tag tag = tagService.getOne(wrapper);
			if (tag != null) {
				boolean isFail = false;
				for (String failAddr : failShortAddrs) {
					if (failAddr.equals(st)) {
						isFail = true;
						failTags.add(tag.getIp());
						break;
					}
				}
				if (isFail == false) {
					successTags.add(tag.getIp());
				}
			}
		}

		Map<String, Object> result = new HashMap<>();
		result.put("readerCode", hostNumber);
		result.put("led1", ledStateParse(led1State));
		result.put("led2", ledStateParse(led2State));
		result.put("led3", ledStateParse(led3State));
		result.put("led4", ledStateParse(led4State));
		result.put("successTags", successTags);
		result.put("failTags", failTags);

		NewLightMQMessage mes = new NewLightMQMessage();
		mes.setActioncode("activeTag");
		mes.setGUID(String.valueOf(DateUtil.date().getTime()));
		mes.setPostdata(result);
		topicSender.send("wh.reader." + hostNumber + ".message", JSON.toJSONString(mes));
		logger.info("=========activeTag=======" + JSON.toJSONString(mes));
		return null;
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub

	}

	private String ledStateParse(String value) {
		switch (value) {
		case "00":
			return ActiveTagData.OFF_STATE;
		case "01":
			return ActiveTagData.FLASH_STATE;
		case "10":
			return ActiveTagData.X_FLASH_STATE;
		case "11":
			return ActiveTagData.LIGHT_STATE;
		default:
			return ActiveTagData.UNKNOWN;
		}
	}
}
